////////////////////////////////
//typess.lua
//Defines types
//WORKS
////////////////////////////////

/*
bbb.registertype({
	name="", //Name of the type
	is=function (input) //Function to check if it is that type
		...
	end,
	tostring=function (input) //Function to convert this type into a string
		...
	end, 
	fromstring=function (input) //Function to convert this type from a string
		...
	end,
	
	(optional)
	suggest=function (input) //Function that returns a table of possible values, given the input
		...
	end
})
*/

//Type defentions
bbb.registertype({
	name="string",
	is=function (input)
		if(type(input)=="string") then return true end
		return false
	end,
	tostring=tostring,
	fromstring=tostring
})

bbb.registertype({
	name="int",
	is=function (input)
		if(type(input)!="number") then return false end
		input=tonumber(input)
		if(math.floor(input)!=input) then return false end
		return true
	end,
	tostring=tostring,
	fromstring=function (input)
		return math.floor(tonumber(input)+.5)
	end
})
bbb.registertype({
	name="float",
	is=function (input)
		if(type(input)!="number") then return false end
		return true
	end,
	tostring=tostring,
	fromstring=tonumber
})
bbb.registertype({
	name="boolean",
	is=function (input)
		if(type(input)!="boolean") then return false end
		return true
	end,
	tostring=function (input)
		if(input) then
			return "1"
		else
			return "0"
		end
	end,
	fromstring=function (input)
		if(input=="1" or input=="true" or input=="on" or input=="yes") then
			return true
		end
		return false
	end
})
bbb.registertype({
	name="Vector",
	is=function (input)
		if(type(input)!="Vector") then return false end
		return true
	end,
	tostring=tostring,
	fromstring=function (input)
		local first=string.find(input," ",1,true)
		local last=string.find(input," ",first+1,true)
		return Vector(tonumber(string.sub(input,1,first-1)),
		tonumber(string.sub(input,first+1,last-1)),
		tonumber(string.sub(input,last+1)))
	end
})
bbb.registertype({
	name="Angle",
	is=function (input)
		if(type(input)!="Angle") then return false end
		return true
	end,
	tostring=tostring,
	fromstring=function (input)
		local first=string.find(input," ",1,true)
		local last=string.find(input," ",first+1,true)
		return Angle(tonumber(string.sub(input,1,first-1)),
		tonumber(string.sub(input,first+1,last-1)),
		tonumber(string.sub(input,last+1)))
	end
})
bbb.registertype({
	name="table",
	is=function (input)
		if(type(input)!="table") then return false end
		return true
	end,
	tostring=bbb.tabletostring, //See tableparse.lua
	fromstring=bbb.stringtotable
})
//This is a fakeish type, so I can to bbb.tabletostring(bbb)
bbb.registertype({
	name="function",
	is=function (input)
		if(type(input)!="function") then return false end
		return true
	end,
	tostring=tostring, //See tableparse.lua
	fromstring=tostring
})
//This is a fakeish type, so I can to bbb.tabletostring(bbb)
bbb.registertype({
	name="Player",
	is=function (input)
		if(type(input)!="Player") then return false end
		return true
	end,
	tostring=function (input)
		return input:SteamID()
	end, //See tableparse.lua
	fromstring=function (input)
		for k,v in ipairs(player.GetAll()) do
			if(v:SteamID()==input) then
				return v
			end
		end
		return false
	end
})
bbb.registertype({
	name="user",
	is=function (input)
		return input:IsPlayer()
	end,
	tostring=function (input)
		if(input:IsPlayer()==true) then
			return input:SteamID()
		end
		return "Unknown Player"
	end,
	fromstring=function (input)
		local out={} //Output is stored in a table, so it can act upon multiple users.
		local name
		//Users are usually stored in a table, so it can act upon multiple people
		for k,v in ipairs(player.GetAll()) do
			//Names are searched through, though steamid's have to be exact.
			name=v:Name()
			if(string.find(string.lower(name),input)!=nil or string.upper(input)==v:SteamID()) then
				table.insert(out,v)
			end
		end
		return out
	end
})
//This is for all functions that need a user string, such as kick.
bbb.registertype({
	name="userstring",
	is=function (input)
		//If the string matches anybody's name...
		
		if(#bbb.fromstring(input,"user")!=0) then
			return true
		end
		return false
	end,
	tostring=tostring,
	fromstring=function (input)
		return bbb.fromstring(input,"user")
	end,
	suggest=function (input)
		//The first three hundred characters of a list of commands that start with input
		local names={}
		for k,v in ipairs(player.GetAll()) do
			table.insert(names,string.lower(v:Name()))
		end
		local suggestions=bbb.list(string.lower(input) or "",names)
		//If you tell it to go from 1 to larger than the table size, it bugs out. In comes math.min
		return table.concat(suggestions," ",1,math.min(6,#suggestions))
	end
})
bbb.registertype({
	name="none",
	is=function (input)
		if(input!=nil) then return false end
		return true
	end,
	tostring=tostring,
	fromstring=function (input)
		return nil
	end
})
bbb.registertype({
	name="command",
	is=function (input)
		//The problem is, for the help function it defaults to help, which isn't defined yet. This is a hacky workaround.
		if(bbb.commands[input]==nil and input!="help") then return false end
		return true
	end,
	tostring=tostring,
	fromstring=tostring,
	suggest=function (input)
		//The first three hundred characters of a list of commands that start with input
		local suggestions=bbb.list(input or "",bbb.commands,true)
		//If you tell it to go from 1 to larger than the table size, it bugs out. In comes math.min
		return table.concat(suggestions," ",1,math.min(6,#suggestions))
	end
})
bbb.registertype({
	name="setting",
	is=function (input)
		//The problem is, for the help function it defaults to help, which isn't defined yet. This is a hacky workaround.
		if(bbb.settings[input]==nil) then return false end
		return true
	end,
	tostring=tostring,
	fromstring=tostring,
	suggest=function (input)
		//The first three hundred characters of a list of commands that start with input
		local suggestions=bbb.list(input or "",bbb.settings,true)
		//If you tell it to go from 1 to larger than the table size, it bugs out. In comes math.min
		return table.concat(suggestions," ",1,math.min(6,#suggestions))
	end
})
